package io.terminus.paas.profiler.service.impl

import com.alibaba.dubbo.common.Constants
import com.alibaba.dubbo.common.URL
import io.terminus.paas.profiler.AbstractProfilerService
import io.terminus.paas.profiler.service.ConfigurationService
import io.terminus.paas.profiler.model.Configuration
import io.terminus.paas.profiler.utils.sync.SyncUtils
import org.springframework.stereotype.Service
import java.net.Inet4Address
import java.util.*

/**
 * Created by gengrong on 16/3/18.
 */
@Service
class ConfigurationServiceImpl : ConfigurationService, AbstractProfilerService() {
    override fun saveConfiguration(registryAddress: String, configuration: Configuration) {
        getRegistryService(registryAddress).register(configuration.toUrl())
    }

    override fun updateOverride(registryAddress: String, configuration: Configuration) {
        val id = configuration.id ?: throw IllegalStateException("no override id")
        val oldOverride = findOverrideUrl(registryAddress, id) ?: throw IllegalStateException("Route was changed!")
        val newOverride = configuration.toUrl()
        getRegistryService(registryAddress).unregister(oldOverride)
        getRegistryService(registryAddress).register(newOverride)
    }

    override fun findByServiceAndAddress(environmentId: String, service: String, address: String): List<Configuration> {
        return SyncUtils.url2OverrideList(findConfigurationUrl(environmentId, service, address, null))
    }

    override fun deleteConfiguration(registryAddress: String, id: Long) {
        val oldOverride = findOverrideUrl(registryAddress, id) ?: throw IllegalStateException("Route was changed!")
        getRegistryService(registryAddress).unregister(oldOverride)
    }

    private fun findConfigurationUrl(registryAddress: String, service: String?, address: String?, application: String?): Map<Long, URL> {
        val filter = HashMap<String, String>()
        filter.put(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY)
        service?.let { filter.put(SyncUtils.SERVICE_FILTER_KEY, service) }
        address?.let { filter.put(SyncUtils.ADDRESS_FILTER_KEY, address) }
        application?.let { filter.put(Constants.APPLICATION_KEY, application) }
        return SyncUtils.filterFromCategory(getRegistryCache(registryAddress), filter)
    }

    fun findOverrideUrl(registryAddress: String, id: Long): URL? {
        return findById(registryAddress, id)?.toUrl()
    }


    fun findById(registryAddress: String, id: Long): Configuration? {
        return SyncUtils.url2Configuration(findConfigurationUrlById(registryAddress, id))
    }

    private fun findConfigurationUrlById(registryAddress: String, id: Long): Map.Entry<Long, URL>? {
        return SyncUtils.filterFromCategory(getRegistryCache(registryAddress), Constants.CONFIGURATORS_CATEGORY, id)
    }

}